import { changeCount, delSelect, getCartList } from '@/api/cart'
import { Toast } from 'vant'

export default {
  namespaced: true,

  state () {
    return {
      /**
       * 用户的购物车列表
       * 返回的数据格式如下：
          "status": 200,
          "message": "success",
          "data": {
              "cartTotal": 3, // 没用
              "list": [
                  {
         这里的cartList = data.list，可以参考getCartAction函数
       */
      cartList: []
    }
  },

  /**
   * mutations是用来提供修改数据的方法的
   */
  mutations: {
    /**
     * 提供一个设置 cartList 的 mutation
     * @param {Object} state
     * @param {Object} newList
     */
    setCartList (state, newList) {
      state.cartList = newList
    },

    /**
     * isChecked取反的函数
     * @param {Object} state
     * @param {Object} goodsId
     */
    toggleCheck (state, goodsId) {
      // 让对应的 id 的项 状态取反
      const goods = state.cartList.find(item => item.goods_id === goodsId)
      goods.isChecked = !goods.isChecked
    },

    /**
     * 全选的设置，同时修改所有的isChecked = flag
     * @param {Object} state
     * @param {Object} flag
     */
    toggleAllCheck (state, flag) {
      // 让所有的小选框，同步设置
      state.cartList.forEach(item => {
        item.isChecked = flag
      })
    },

    /**
     * 修改vuex中存的数据：更新商品的数量
     */
    changeCount (state, { goodsId, goodsNum }) {
      const goods = state.cartList.find(item => item.goods_id === goodsId)
      goods.goods_num = goodsNum
    }
  },

  /**
   * 异步操作放actions里面
   */
  actions: {
    /**
     * 从后台拿到购物车列表的数据，并给每条数据加上 isChecked 属性
     * @param {Object} context
     */
    async getCartAction (context) {
      const { data } = await getCartList() // 获取购物车列表的后端接口
      /**
       * 后台返回的数据中，不包含复选框的选中状态，为了实现将来的功能，
       * 需要手动维护数据，给每一项，添加一个 isChecked 状态 (标记当前商品是否选中)
       */
      data.forEach(item => {
        item.isChecked = true // 都给整个true，让用户多买
      })
      // 保存到vuex中
      context.commit('setCartList', data)
    },

    /**
     * 修改购物车中的商品数量，并发送数据到后台
     * @param {Object} context
     * @param {Object} obj
     */
    async changeCountAction (context, obj) {
      const { goodsNum, goodsId, goodsSkuId } = obj
      // 先本地修改，否则需要刷新重新获取购物车列表，才能看到更新后的后台数据
      context.commit('changeCount', { goodsId, goodsNum })
      // 再同步到后台，不需要要相应数据，主要是告诉后台我改了
      await changeCount(goodsId, goodsNum, goodsSkuId)
    },

    /**
     * 删除购物车数据
     * @param {Object} context
     */
    async delSelect (context) {
      const selCartList = context.getters.selCartList // 返回选中的列表数据
      const cartIds = selCartList.map(item => item.id) // 取到所有的id，放到一个新的列表中，这就是需要删除的id列表
      await delSelect(cartIds) // 请求后端
      Toast('删除成功')

      // 重新拉取最新的购物车数据 (重新渲染)
      context.dispatch('getCartAction')
    }
  },

  /**
   * getters用来提供一些基于state派生出来的属性的
   */
  getters: {
    /**
     * 求购物车中所有商品的总数，返回数量
     * @param {Object} state
     */
    cartTotal (state) {
      // 累加每种商品买了多少件
      return state.cartList.reduce((sum, item) => sum + item.goods_num, 0)
    },

    /**
     * 选中的商品项，返回列表
     * @param {Object} state
     */
    selCartList (state) {
      return state.cartList.filter(item => item.isChecked)
    },

    /**
     * 选中的商品总数
     * @param {Object} state
     * @param {Object} getters 拿到其他的getters
     */
    selCount (state, getters) {
      return getters.selCartList.reduce((sum, item) => sum + item.goods_num, 0)
    },

    /**
     * 选中的总价
     * @param {Object} state
     * @param {Object} getters
     */
    selPrice (state, getters) {
      return getters.selCartList.reduce((sum, item) => {
        return sum + item.goods_num * item.goods.goods_price_min
      }, 0).toFixed(2)
    },

    /**
     * 是否全选
     * @param {Object} state
     */
    isAllChecked (state) {
      return state.cartList.every(item => item.isChecked)
    }
  }
}
